在本书中,JRockit JVM的安装目录以JROCKIT_HOME指代,将之设为系统变量可以使操作更简便。在安装完成后,顺便将JROCKIT_HOME/bin目录添加到PATH路径中,建议将环境变量JAVA_HOME的值设置为JROCKIT_HOME指代的目录。大部分情况下,JRockit都可以直接替代其他JVM,但某些启动参数需要调整,例如某些控制具体垃圾回收行为的参数,这在不同JVM厂商之间有较大差别。其他一些比较通用的参数,例如设置堆大小的最大值,在设置的时候是相同的。
更多有关迁移应用程序到JRockit JVM的详细信息,请参见JRockit在线文档中 Migrating Applications to the Oracle JRockit JDK 一章的内容。
在JRockit JVM中,有3类命令行选项,分别是系统属性、标准命令行选项(以-X开头)和非标准命令行选项(以-XX开头)。
有几种不同的方式设置JVM参数。以-D开头的参数会用来设置相应的系统属性,这些属性可以为Java类库,如RMI等,提供相关的配置信息。例如,如果设置了-Dcom.jrockit.mc.debug=true参数,则JRockit Mission Control会打印出调试信息。不过,在R28之后的JRockit JVM废弃了很多之前使用过的系统属性,而是采用非标准命令行选项和HotSpot中的方式设置相关选项。
以-X开头的命令行选项是大部分JVM厂商都支持的通用设置。例如,用于设置堆大小最大值的选项-Xmx,这在包括JRockit在内的大部分JVM中都是相同的。当然,也不是所有的都相同,JRockit中的选项-Xverbose会打印出可选的子模块,而在HotSpot中,对应的选项是-verbose。
以-XX开头的命令行选项是各个JVM厂商自己定制的。这些选项可能会在将来的某个版本中被废弃或修改。如果JVM的参数配置中包含了以-XX开头的命令行选项,并且将Java应用程序从一种JVM迁移到另一种,则在启动JVM之前,应该先去除这些非标准命令行选项。当确定了新的JVM选项后才可以启动Java应用程序。一般情况下,Java应用程序迁移到JRockit JVM后,在内存消耗上会有些许增加,但能够获得更好的性能。为了更好的确定JVM选项,应该通过查询JVM文档来确定不同JVM厂商之间、不同JVM版本之间的非标准命令行选项是否具有相同的含义。
JRockit R28之后的版本,添加了称为 VM标志 命令行选项,作为非标准命令行选项的子集使用,其语法是: -XX:<flag>=<value>。使用命令行工具JRCMD可以读取这些VM标志的值,并且可以修改某些VM标志的值。更多关于JRCMD的内容,请参见第11章。
不同的JVM可能会有不同的运行时行为,通常这是因为不同JVM对Java语言规范和JVM规范有不同的实现。规范中的很多地方没有做强制规定,为JVM厂商实现出独具特色的功能留出余地。如果某个应用程序严重依赖于规范的某种具体实现,那么迁移该应用程序到其他规范实现时恐怕就不那么容易了。
例如,曾经在对Eclipse的里程碑版本进行测试时,某些测试内容无法在JRockit上启动。后来发现,这些测试之间具有依赖性,测试需要以特定的顺序进行。而JRockit对通过反射获取的方法列表的实现与其他JVM不同,尽管这并不违反规范,但却导致了测试无法正常进行。后来,Eclipse的开发团队修正了这个bug。
如果在编写应用程序时不遵守规范,而是以某款JVM的特殊行为作为依据,那么该应用程序将无法正确运行,甚至当使用同一个JVM厂商的新版本JVM时,也会出错。如果编写应用程序时遇到相关问题,请查阅Java语言规范和JDK相关文档。
迁移到新JVM时,两款JVM之间的性能差异往往是最受关注的,而潜在bug却容易为忽视,例如由于性能有差别,事件的触发时间会与之前稍有不同。这些事情可能会导致一些问题的发生,但不应将之归咎于JVM。
例如,曾有用户报告说,JRockit只运行了一天就奔溃了。经过调查发现,该客户的应用程序运行在其他JVM上时,也会发生崩溃,只不过是多运行几天才崩溃。之所以JRockit崩溃的更快,是因为该应用程序在JRockit上运行的更快,内存泄漏的速度更快而已。
当然,所有的JVM,包括JRockit,都还有有一些bug存在。为了标榜自己是 Java 虚拟机,JVM实现都必须使用Java Compatibility Kit(JCK)进行大量的兼容性测试。
JRockit一直是使用分布式测试系统进行各种测试的。这个大测试套件中包含了JCK,通过这个测试以保证发布的JRockit是一款稳定的、兼容Java的、合格的JVM。在发行新版本JRockit之前,会使用该测试套件,在JRockit运行各种应用程序,例如Eclipse、WebLogic Server和专门设计用来进行压力测试的程序,这些测试会在所有受支持的平台上进行以测试JRockit是否有bug,此外对性能做持续的回归测试也是JRockit QA工作的重中之重。但即便如此,bug仍然无法避免。如果JRockit崩溃了,请将详细情况报告给Oracle的支持工程师。